package com.gitee.huanminabc.utils_common.obj;

import com.gitee.huanminabc.jcommon.multithreading.executor.ExecutorUtil;
import com.gitee.huanminabc.jcommon.multithreading.executor.ThreadFactoryUtil;
import io.github.classgraph.ClassGraph;
import io.github.classgraph.ClassInfoList;
import io.github.classgraph.ScanResult;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

//扫描类工具
public class ScanClassUtil {

    //通过接口获取所有实现的子类
    public static Map<String, String> getSubClassByInterface(Class<?>... interfaceClass) {
        try (ScanResult scanResult = new ClassGraph()
                .enableClassInfo() // 扫描类信息
                .enableSystemJarsAndModules() // 扫描系统类,如java.* 和 javax.* 等
                .scan()) {
            ThreadPoolExecutor executor = ThreadFactoryUtil.getExecutor("&ScanClassUtilPool&");
            Map<String, String> mapDepend = new ConcurrentHashMap<>();
            List< Future<?>> futureList = new ArrayList<>();
            for (Class<?> aClass : interfaceClass) {
                Future<?> submit = executor.submit(() -> {
                    //这样做的目的是为了获取所有实现类的名称不加载类,否则有些类依赖不全会报错不要调用loadClasses
                    ClassInfoList classesImplementing = scanResult.getClassesImplementing(aClass.getName());
                    List<String> names = classesImplementing.getNames();
                    for (String name : names) {
                        //截取类名
                        String[] split = name.split("\\.");
                        mapDepend.put(split[split.length - 1], name);
                    }
                });
                futureList.add(submit);
            }
            ExecutorUtil.waitComplete(futureList);
            return mapDepend;
        }
    }

    public static void main(String[] args) {
        Map<String, String> subClassByInterface = getSubClassByInterface(Collection.class);
        System.out.println(subClassByInterface);

    }
}
